perm filename TCPRX.MAC[IP,SYS] blob
sn#680230 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-TCP>TCPRX.MAC.40303 4-May-82 13:56:59, Edit by CLYNN
; Refresh IP options on each retransmission; newer RX algorithm
;<403-TCP>TCPRX.MAC.40301 29-Jan-82 15:08:04, Edit by CLYNN
; Updated for TCP release 3
; Parameters moved to STG, TRACEP becomes INTTRC
;[BBNF]<401-TCP>TCPRX.MAC.56, 10-Jul-81 15:38:00, Ed: CLYNN
; Fix: No room in RXINI
SEARCH INPAR,TCPPAR,PROLOG
TTITLE TCPRX
SUBTTL TCP Retransmitter, William W. Plummer, 15FEB77
SWAPCD
COMMENT !
The Retransmitter task is call from the top level of the TCP
when a connection deadline has elapsed. The single packet at
the head of the restransmission queue is sent again and its
retranmission interval adjusted. Should the maximum
persistence of some message be exceeded, the user is notified
and the connection aborted.
* REXMIT ... 3 ...... Retransmitter
* SETRXP ... 7 ...... Set up Retransmission parameters in a PKT
* RXPARS ... 8 ...... Change retransmission parameters
* RXINI .... 9 ...... Initialize RX process block
Two retransmission strategies are available. The old initial
interval with backoff and the "newer" dynamic method.
The "newer" method is the default; it is specified by a "retransmission
parameters word" (OPEN, SEND) of zero. It uses a smoothed round trip
time estimate based on the formula
SRTT = SRTT(last) * alpha + RTT * (1-alpha)
and the packet retransmission interval is computed by
RXI = SRTT * beta
where SRTT is TSMRT (initial value is TCPRX0)
alpha is TCPRXS (scaled by 2**-(TCPRXF))
RTT is TODCLK(ACK)-PTG
beta is TCPRXV (scaled by 2**-(TCPRXF))
RXI is PRXI
The old method is specified if the "retransmission parameters word" has
ever been non-zero. It computes the minimum and maximum round trip times
for all packets in a TCPBG0 msec interval and then sets the estimated
retransmission time (TRXI, initial value from RX param word, or TCPDXI if 0)
to one-half second above the average estimated round trip time. With each
retransmission of a packet, the next retransmission interval is the current
value * numinator / denominator (each from the RX param word or TCPDXN,
TCPDXD).
!
; REXMIT Retransmit for a connection
;TCB/ (Extended) Locked connection block. (Dequeued from RX queue)
;
; CALL REXMIT
;Ret+1: Always
REXMIT::LOCAL <LINBLK,NXRXI>
PUSH P,PKT
PUSH P,TPKT
XMOVEI T1,TCBRXQ(TCB) ; Pointer to the retranmit queue
LOAD PKT,QNEXT,(T1) ; Set pointer to first thing on queue
SETSEC PKT,INTSEC ; Make extended address
SETO LINBLK, ; Assume not a TVT
CAMN PKT,T1 ; If that is the head of the queue,
JRST REXMIX ; we are done.
; TVT processing
JE TTVT,(TCB),REXM1B ; Jump if not a TVT
JUMPGE LINBLK,REXM1B ; Jump if already have line locked
LOAD T2,TVTL,(TCB) ; Get the line number
JUMPLE T2,REXM1B ; TVTL may be 0 if RXing a SYN
CALL LCKTTY ; Lock and get ptr to dynamic block
JUMPLE T2,REXM1A ; Not init'd yet
MOVEM T2,LINBLK
JRST REXM1B
REXM1A: CALL ULKTTY
REXM1B:
; Common processing
LOAD T1,PIDO,(PKT) ; Internet data offset in words
XMOVEI TPKT,PKTELI(PKT) ; Pointer to Internet portion
ADD TPKT,T1 ; Pointer to TCP portion
SKIPN TCPON ; Force error if TCP is turned off
JRST REXMI2
; If this is the first retransmission of this packet, reinitialize
; the retransmission parameters (Initial interval and discard
; time). Since this is done as each packet appears at Send.Left,
; timeouts are avoided in the case where the receiver is very slow.
JN PRXD,(PKT),REXM11 ; Pkt has been RX'd at least once
LOAD T1,PSEQ,(TPKT) ; Packet sequence number
LOAD T2,TSLFT,(TCB) ; Send Left
LOAD T3,PESEQ,(PKT) ; End sequence of the Packet
CALL CHKWND ; Is Left within this Pkt?
JUMPE T1,REXMI3 ; No. Retransmit if needed.
CALL SETRXP ; Initialize the RX parameters
REXM11:
; This packet contains TSLFT or has already been retransmitted
; Check for Retransmission timeout
LOAD T1,PDCT,(PKT) ; Get discard time for this pkt
JUMPE T1,REXMI3 ; Jump if no discard time specified
CAML T1,TODCLK ; Packet undeliverable?
JRST REXMI3 ; Not yet.
; A pkt has not been ACKed within the (send) timeout specified
; by the user, or TCP has been shut off (TCPON is 0)
REXMI2: MOVEI T1,ELP+↑D9 ; "Retransmission timeout"
CALL USRERR ; Tell the user
MOVEI T1,ELP+↑D14 ; "Connection reset"
CALL ABTCON ; Abort the connection
JRST REXMIX ; Return to caller
; See if it is time to retransmit this packet.
REXMI3: LOAD NXRXI,PRXI,(PKT) ; Get the current retransmit interval
JN PINTL,(PKT),REXMI6 ; Cannot RX if last still unsent
LOAD T1,PXT,(PKT) ; Time of last transmission
ADD NXRXI,T1 ; Plus interval is time to RX
SUB NXRXI,TODCLK ; Time before next RX
JUMPG NXRXI,REXMI6 ; Not yet time, go reschedule
; Re-transmit the packet. Refresh IP options that might have been changed
CALL TCPIIO ; Hope user hasn't changed them
MOVE NXRXI,TCPRXW ; Time to use if zero window (note that
JE TSWND,(TCB),REXM36 ; PRXI is unchanged but won't look til later)
JE <TRXPN,TRXPD>,(TCB),REXM32 ; Use newer method
LOAD T1,PRXI,(PKT) ; Get the current retransmit interval
LOAD T2,TRXPN,(TCB) ; Numerator of backoff ratio
LOAD T3,TRXPD,(TCB) ; Denominator
IMULI T1,0(T2)
IDIVI T1,0(T3)
JRST REXM34
; Estimates based only on round trip time are essentially constant
; retransmissions, which looses if a large round trip time is usual.
REXM32: JN PRXD,(PKT),REXM33 ; Jump if multiple retransmissions
LOAD T1,TSMRT,(TCB) ; Current round trip estimate
IMUL T1,TCPRXV ; Increase by (scaled) variance
ASH T1,@TCPRXF ; Remove scale factor
JRST REXM34
; Until we have the estimate use a backoff factor of about 2.
REXM33: LOAD T2,PTG,(PKT) ; Time packet generated
MOVE T1,TODCLK ; Now
SUB T1,T2 ; Time packet has been unACKed
; Essentially doubles RX interval
REXM34:
CAMLE T1,TCPRXX ; Limit to maximum
MOVE T1,TCPRXX
STOR T1,PRXI,(PKT) ; Store back in the packet header
MOVEM T1,NXRXI ; Save for signal
REXM36:
; Before queueing the packet for an interface, set RXd flag
SETONE PRXD,(PKT) ; Indicate that packet has been RXd
MOVX T1,PT%XX8 ; Code for "being retransmitted"
TDNE T1,INTTRC ; Want trace?
CALL PRNPKT ; Yes, tell the packet printer
REPEAT 0,<
SKIPN STATF ; Taking statistics right now?
JRST REXMI4 ; No.
MOVEI T1,RXDLAY ; Select a histogram
CALL TSTAMP ; Process the timestamp
XMOVEI T1,OPUSE ; Select a time accumulator
XMOVEI T2,EMTPKT ; Function to call
MOVE T3,LINBLK ; TVT block if any
CALL TIMCAL ; Time the call
JRST REXMI5 ; Go handle the next packet
REXMI4:
> ; End of REPEAT 0
MOVE T1,LINBLK ; TVT block if any
CALL EMTPKT ; Send off the packet
REXMI5:
AOS RXPKCT ; Count retransmitted packets
; Now reschedule Retransmitter to run again when this packet should
; again be retransmitted
REXMI6: XMOVEI T1,RX ; What to signal
MOVE T2,NXRXI ; The desired interval
CALL SIGNAL ; Cause ourself to run later
REXMIX: SKIPL T2,LINBLK ; Running for a TVT?
CALL ULKTTY ; Yes. Unlock it
POP P,TPKT
POP P,PKT
RESTORE
RET
; SETRXP (PKT, TCB) Initialize retransmission parameters in a pkt
;PKT/ (Extended) Packet pointer
;(TPKT/ (Extended) pointer to TCP part of packet)
;TCB/ (Extended) Locked connection block
;
; CALL SETRXP
;Ret+1: Always
SETRXP::
; Set packet discard time
; How should Source-quench & send timeout interact?
LOAD T1,TSTO,(TCB) ; Send time out set by user
SKIPE T1 ; Use 0 if none specified
ADD T1,TODCLK ; Else compute the deadline
STOR T1,PDCT,(PKT) ; Set the discard time in the packet
; Set initial retransmission interval
JE <TRXPN,TRXPD>,(TCB),SETRX4 ; Use newer method
LOAD T1,TRXI,(TCB) ; Get estimated Retrans. Interval.
SKIPG T1 ; Guard against bad extimate of rnd trip
MOVE T1,TCPDXI ; Choose default interval in that case
LOAD T2,TRXPI,(TCB) ; Get possible user setting
IMULI T2,↑D1000 ; Convert to milliseconds
SKIPE T2 ; Did user set retrans parameters?
MOVE T1,T2 ; Yes. Use that initial interval
JRST SETRX6
SETRX4: LOAD T1,TSMRT,(TCB) ; Get estimated round trip time
IMUL T1,TCPRXV ; Increase by (scaled) variance
ASH T1,@TCPRXF ; Remove scale factor
SETRX6:
CAMLE T1,TCPRXX ; Keep within bounds
MOVE T1,TCPRXX
CAMGE T1,TCPRXN ; both ends.
MOVE T1,TCPRXN
SKIPE INTTRC ; Actively tracing packets?
IMULI T1,↑D1 ;8 ; Slow down retransmissions
STOR T1,PRXI,(PKT) ; Set packet retrans interval
RET
; RXPARS(TCB) Change retransmission parameters
; Called by SEND and OPEN which allow the caller to change the
; retransmission characteristics -- Backoff rate and initial
; retransmission interval.
;TCB/ (Extended) Locked Connection Block
;T1/ Retrans. parameter word. Format is that of TRXP.
;
; CALL RXPARS
;Ret+1: Always.
;Note: Newly created TCBs have 0 in the TRXP word which
;means that the user has not chosen to override the use of
;measured round trip time as the way of selecting the retrans
;interval. If the user sets TRXP, those parameters are used.
RXPARS::JUMPE T1,RXPARX ; No change wanted
LOAD T2,TRXP,(TCB) ; Current settings
CAMN T1,T2 ; Different?
JRST RXPARX ; No.
; NOSKED
STOR T1,TRXP,(TCB) ; Put them in place for LOADs
LOAD T2,TRXPN,(TCB) ; Get numerator
LOAD T3,TRXPD,(TCB) ; and denominator of backoff fraction
LOAD T4,TRXPI,(TCB) ; Initial interval in seconds
; OKSKED
SKIPN T2 ; Get defaults
MOVE T2,TCPDXN
SKIPN T3
MOVE T3,TCPDXD
SKIPN T4
MOVE T4,TCPDXI
CAMLE T3,T2 ; Prevent interval from decreasing
MOVE T3,T2
STOR T2,TRXPN,(TCB) ; Set it all into the TCB
STOR T3,TRXPD,(TCB)
STOR T4,TRXPI,(TCB)
RXPARX: RET
; RXINI Initialize RX process block
; CALL RXINI
;Ret+1: ALways, T1 zero if error
RXINI:: LOCAL <PRC>
XMOVEI PRC,RX ; Pointer to the Process block for RX
MOVX T1,QSZ ; Size of a queue head
CALL GETBLK ; Head must be in same section as items
JUMPE T1,RXINIX ; No room
MOVEM T1,PRCQ(PRC) ; Input queue
CALL INITQ ; Initialize it
XMOVEI T1,PRCLCK(PRC) ; Lock
CALL CLRLCK ; Initilize it
XMOVEI T1,REXMIT ; Retransmitter function
MOVEM T1,PRCROU(PRC) ; Routine address
SETOM PRCWAK(PRC) ; No run time yet
MOVE T1,[<GIW TCBQRX,TCB>]; Offset of RX queue in TCB
MOVEM T1,PRCQOF(PRC) ; Store process block
MOVE T1,[<GIW TCBTRX,TCB>]; Offset of RX run time in TCB
MOVEM T1,PRCWOF(PRC) ; Store in process block
HRLOI T1,377777 ; Infinity
MOVEM T1,PRCSGT(PRC) ; Set time of most recent signal
XMOVEI T1,RXRNCT ; Pointer to run counter
MOVEM T1,PRCRNC(PRC) ; Put in standard place
XMOVEI T1,RXUSE ; Pointer to CPU use meter
MOVEM T1,PRCTMR(PRC) ; Put in standard place
; SETO T1,
RXINIX: RESTORE
RET
TNXEND
END